<?xml version="1.0"?>
<!-- $Id: perl.xml,v 1.1 2007/06/03 02:35:28 ssttoo Exp $ -->

<highlight lang="perl" case = "yes">

  <authors>
    <author name="Mariusz 'kg' Jakubowski" email="kg@alternatywa.info" jid="kg@chrome.pl"/>
    <author name="Andrey Demenev" email="demenev@gmail.com"/>
  </authors>

  <comment>This highlighter is EXPERIMENTAL, so that it may work incorrectly. 
Most rules were created by Mariusz Jakubowski, and extended by me.
My  knowledge  of  Perl  is  poor,  and  Perl  syntax  seems  too
complicated to me.</comment>

  <default innerClass="code"/>

  <block name="interpreter" match="/^(#!)(.*)/m" innerClass="special">
   <partClass index="1" innerClass="special" />
   <partClass index="2" innerClass="string" />
  </block>

  <region name="pod" innerClass="comment" start="/^=\w+/m" end="/^=cut[^\n]*/m" startBOL="yes" endBOL="yes"/>

  <!-- 
  brackets 
  -->
  <region name="block" delimClass="brackets" innerClass="code" start="\{" end="\}">
    <contains all="yes"/>
  </region>

  <region name="brackets" delimClass="brackets" innerClass="code" start="\(" end="\)">
    <contains all="yes"/>
  </region>

  <region name="sqbrackets" delimClass="brackets" innerClass="code" start="\[" end="\]">
    <contains all="yes"/>
  </region>

  <!-- 
  use smth 
  -->
  <block name="usestatement" match="(use)\s+([\w:]*)" innerClass="special">
   <partClass index="1" innerClass="reserved" />
   <partClass index="2" innerClass="special" />
  </block>
  
  <block name="packagereference" match="[&amp; ](\w{2,}::)+\w{2,}" innerClass="special"/>

  <region name="q-w-q-statement" 
    start="/\b(q[wq]\s*((\{)|(\()|(\[)|(\&lt;)|([\W\S])))(?=(.*)((?(3)\})(?(4)\))(?(5)\])(?(6)\&gt;)(?(7)\7)))/Us"
    end="%b2%"
    innerClass="string" delimClass="quotes" remember="yes">

    <contains block="containedvar"/>
    <contains block="specialvar"/>
    <contains block="curlyvar"/>

  </region>

  <region name="qstatement" 
    start="/\b(q\s*((\{)|(\()|(\[)|(\&lt;)|([\W\S])))(?=(.*)((?(3)\})(?(4)\))(?(5)\])(?(6)\&gt;)(?(7)\7)))/Us"
    end="%b2%"
    innerClass="string" delimClass="quotes" remember="yes">

  </region>

  <!-- 
  comments 
  -->
  <block name="comment" match="#.*" innerClass="comment" />
  
  
  <!-- 
  regexpr
  FIXME: this should be rewrited
  -->
  <block name="dblregexprver1" match="/(s|tr) ([|#~`!@$%^&amp;*-+=\\;:'&quot;,.\/?])  ((\\.|[^\\])*?) (\2)((\\.|[^\\])*?)(\2[ecgimosx]*)/x" innerClass="string">
   <partClass index="1" innerClass="quotes" />
   <partClass index="2" innerClass="quotes" />
   <partClass index="3" innerClass="string" />
   <partClass index="5" innerClass="quotes" />
   <partClass index="6" innerClass="string" />
   <partClass index="8" innerClass="quotes" />
  </block>
  
  <block name="dblregexprver2" match="/(m) ([|#~`!@$%^&amp;*-+=\\;:'&quot;,.\/?])  ((\\.|[^\\])*?) (\2[ecgimosx]*)/x" innerClass="string">
   <partClass index="1" innerClass="quotes" />
   <partClass index="2" innerClass="quotes" />
   <partClass index="3" innerClass="string" />
   <partClass index="5" innerClass="quotes" />
  </block>
  

  <region name="regexp" start=" \/" end="\/[cgimosx]*" innerClass="string" delimClass="quotes" case="yes">
    <contains block="reescaped"/>
  </region> 
  
  <block name="reescaped" match="\\\/" innerClass="string" contained="yes">
    <onlyin region="regexp"/>
  </block> 
  
  <!-- 
  variables 
  FIXME: @{...} 
  -->
  <block name="bracketsvars" match="([a-z1-9_]+)(\s*=>)" innerClass="string" contained="yes" case="no">
    <partClass index="1" innerClass="string" />
    <partClass index="2" innerClass="code" />
    <onlyin region="brackets"/>
  </block>

  <block name="specialvar" match="\$#?[1-9'`@!]" innerClass="var"/>
  
  <block name="var" match="(\$#?|[@%*])([a-z1-9_]+::)*([a-z1-9_]+|\^(?-i)[A-Z]?(?i))" innerClass="var" case="no"/>
  <block name="containedvar" match="\$([a-z1-9_]+|\^(?-i)[A-Z]?(?i))" innerClass="var" case="no"/>

  <!-- not shure what is this, but the Perlers do it :) -->
  <block name="var2" match="(&amp;|\w+)'[\w_']+\b" innerClass="var" case="no"/>

  <block name="classvar" match="(\{)([a-z1-9]+)(\})" innerClass="var" case="no">
   <partClass index="1" innerClass="brackets" />
   <partClass index="2" innerClass="var" />
   <partClass index="3" innerClass="brackets" />
  </block>

  <block name="curlyvar" match="[\$@%]#?\{[a-z1-9]+\}" innerClass="var" case="no"/>

  <!-- 
  quotes
  -->
  <region name="exec" delimClass="quotes" innerClass="string" start="`" end="`">
    <contains block="containedvar"/>
    <contains block="specialvar"/>
    <contains block="curlyvar"/>
  </region>

  <region name="strsingle" delimClass="quotes" innerClass="string" start="'" end="'"/>

  <block name="escaped" match="\\\\|\\&quot;|\\'|\\`" innerClass="special" contained="yes">
    <onlyin region="qstatement"/>
    <onlyin region="strsingle"/>
    <onlyin region="exec"/>
  </block>

  <region name="strdouble" delimClass="quotes" innerClass="string" start="&quot;" end="&quot;">
    <contains block="containedvar"/>
    <contains block="specialvar"/>
    <contains block="curlyvar"/>
  </region>

  <block name="descaped" match="\\[\\&quot;'`tnr\$\{@]" innerClass="special" contained="yes">
    <onlyin region="strdouble"/>
    <onlyin region="q-w-q-statement"/>
  </block>
 
  <!-- logical op. 
  <block name="logic" match="\|\||&amp;&amp;" innerClass="reserved" contained="yes"/>-->
 
  <!-- 
  identifiers 
  -->
  <block name="identifier" match="[a-z_]\w*" innerClass="identifier" case="no"/>

  <!-- 
  numbers 
  -->
  <block name="number" match="\d*\.?\d+" innerClass="number"/>

  <!-- 
  http://www.perldoc.com/perl5.6/pod/perlfunc.html 
  Alphabetical Listing of Perl Functions 
  -->
  <keywords name="reserved" inherits="identifier" innerClass="reserved" case = "yes">
      <keyword match="abs"/>
      <keyword match="accept"/>
      <keyword match="alarm"/>
      <keyword match="atan2"/>
      
      <keyword match="bind"/>
      <keyword match="binmode"/>
      <keyword match="bless"/>
      
      <keyword match="caller"/>
      <keyword match="chdir"/>
      <keyword match="chmod"/>
      <keyword match="chomp"/>
      <keyword match="chop"/>
      <keyword match="chown"/>
      <keyword match="chr"/>
      <keyword match="chroot"/>
      <keyword match="close"/>
      <keyword match="closedir"/>
      <keyword match="connect"/>
      <keyword match="continue"/>
      <keyword match="cos"/>
      <keyword match="crypt"/>

      <keyword match="dbmclose"/>
      <keyword match="dbmopen"/>
      <keyword match="defined"/>
      <keyword match="delete"/>
      <keyword match="die"/>
      <keyword match="do"/>
      <keyword match="dump"/>
      
      <keyword match="each"/>
      <keyword match="endgrent"/>
      <keyword match="endhostent"/>
      <keyword match="endnetent"/>
      <keyword match="endprotoent"/>
      <keyword match="endpwent"/>
      <keyword match="endservent"/>
      <keyword match="eof"/>
      <keyword match="eval"/>
      <keyword match="exec"/>
      <keyword match="exists"/>
      <keyword match="exit"/>
      <keyword match="exp"/>
      
      <keyword match="fcntl"/>
      <keyword match="fileno"/>
      <keyword match="flock"/>
      <keyword match="fork"/>
      <keyword match="format"/>
      <keyword match="formline"/>
      
      <keyword match="getc"/>
      <keyword match="getgrent"/>
      <keyword match="getgrgid"/>
      <keyword match="getgrnam"/>
      <keyword match="gethostbyaddr"/>
      <keyword match="gethostbyname"/>
      <keyword match="gethostent"/>
      <keyword match="getlogin"/>
      <keyword match="getnetbyaddr"/>
      <keyword match="getnetbyname"/>
      <keyword match="getnetent"/>
      <keyword match="getpeername"/>
      <keyword match="getpgrp"/>
      <keyword match="getppid"/>
      <keyword match="getpriority"/>
      <keyword match="getprotobyname"/>
      <keyword match="getprotobynumber"/>
      <keyword match="getprotoent"/>
      <keyword match="getpwent"/>
      <keyword match="getpwnam"/>
      <keyword match="getpwuid"/>
      <keyword match="getservbyname"/>
      <keyword match="getservbyport"/>
      <keyword match="getservent"/>
      <keyword match="getsockname"/>
      <keyword match="getsockopt"/>
      <keyword match="glob"/>
      <keyword match="gmtime"/>
      <keyword match="goto"/>
      <keyword match="grep"/>
      
      <keyword match="hex"/>
      
      <keyword match="import"/>
      <keyword match="index"/>
      <keyword match="int"/>
      <keyword match="ioctl"/>
      
      <keyword match="join"/>
      
      <keyword match="keys"/>
      <keyword match="kill"/>
      
      <keyword match="last"/>
      <keyword match="lc"/>
      <keyword match="lcfirst"/>
      <keyword match="length"/>
      <keyword match="link"/>
      <keyword match="listen"/>
      <keyword match="local"/>
      <keyword match="localtime"/>
      <keyword match="lock"/>
      <keyword match="log"/>
      <keyword match="lstat"/>
      
      <!--<keyword match="m"/>-->
      <keyword match="map"/>
      <keyword match="mkdir"/>
      <keyword match="msgctl"/>
      <keyword match="msgget"/>
      <keyword match="msgrcv"/>
      <keyword match="msgsnd"/>
      <keyword match="my"/>
      
      <keyword match="next"/>
      <keyword match="no"/>
      
      <keyword match="oct"/>
      <keyword match="open"/>
      <keyword match="opendir"/>
      <keyword match="ord"/>
      <keyword match="our"/>
      
      <keyword match="pack"/>
      <keyword match="package"/>
      <keyword match="pipe"/>
      <keyword match="pop"/>
      <keyword match="pos"/>
      <keyword match="print"/>
      <keyword match="printf"/>
      <keyword match="prototype"/>
      <keyword match="push"/>
      
      <!--<keyword match="q"/>
      <keyword match="qq"/>
      <keyword match="qr"/>-->
      <keyword match="quotemeta"/>
      <!--<keyword match="qw"/>
      <keyword match="qx"/>-->
      
      <keyword match="rand"/>
      <keyword match="read"/>
      <keyword match="readdir"/>
      <keyword match="readline"/>
      <keyword match="readlink"/>
      <keyword match="readpipe"/>
      <keyword match="recv"/>
      <keyword match="redo"/>
      <keyword match="ref"/>
      <keyword match="rename"/>
      <keyword match="require"/>
      <keyword match="reset"/>
      <keyword match="return"/>
      <keyword match="reverse"/>
      <keyword match="rewinddir"/>
      <keyword match="rindex"/>
      <keyword match="rmdir"/>
      
      <!--<keyword match="s"/>-->
      <keyword match="scalar"/>
      <keyword match="seek"/>
      <keyword match="seekdir"/>
      <keyword match="select"/>
      <keyword match="semctl"/>
      <keyword match="semget"/>
      <keyword match="semop"/>
      <keyword match="send"/>
      <keyword match="setgrent"/>
      <keyword match="sethostent"/>
      <keyword match="setnetent"/>
      <keyword match="setpgrp"/>
      <keyword match="setpriority"/>
      <keyword match="setprotoent"/>
      <keyword match="setpwent"/>
      <keyword match="setservent"/>
      <keyword match="setsockopt"/>
      <keyword match="shift"/>
      <keyword match="shmctl"/>
      <keyword match="shmget"/>
      <keyword match="shmread"/>
      <keyword match="shmwrite"/>
      <keyword match="shutdown"/>
      <keyword match="sin"/>
      <keyword match="sleep"/>
      <keyword match="socket"/>
      <keyword match="socketpair"/>
      <keyword match="sort"/>
      <keyword match="splice"/>
      <keyword match="split"/>
      <keyword match="sprintf"/>
      <keyword match="sqrt"/>
      <keyword match="srand"/>
      <keyword match="stat"/>
      <keyword match="study"/>
      <keyword match="sub"/>
      <keyword match="substr"/>
      <keyword match="symlink"/>
      <keyword match="syscall"/>
      <keyword match="sysopen"/>
      <keyword match="sysread"/>
      <keyword match="sysseek"/>
      <keyword match="system"/>
      <keyword match="syswrite"/>
      
      <keyword match="tell"/>
      <keyword match="telldir"/>
      <keyword match="tie"/>
      <keyword match="tied"/>
      <keyword match="time"/>
      <keyword match="times"/>
      <!--<keyword match="tr"/>-->
      <keyword match="truncate"/>
      
      <keyword match="uc"/>
      <keyword match="ucfirst"/>
      <keyword match="umask"/>
      <keyword match="undef"/>
      <keyword match="unlink"/>
      <keyword match="unpack"/>
      <keyword match="unshift"/>
      <keyword match="untie"/>
      <keyword match="use"/>
      <keyword match="utime"/>
      
      <keyword match="values"/>
      <keyword match="vec"/>
      
      <keyword match="wait"/>
      <keyword match="waitpid"/>
      <keyword match="wantarray"/>
      <keyword match="warn"/>
      <keyword match="write"/>
      
      <keyword match="y"/> 
  </keywords> 

  <keywords name="missingreserved" inherits="identifier" innerClass="reserved" case = "yes">
      <keyword match="new"/> 
  </keywords> 


  <keywords name="flowcontrol" inherits="identifier" innerClass="reserved" case = "yes">
      <keyword match="if"/> 
      <keyword match="else"/> 
      <keyword match="elsif"/> 
      <keyword match="while"/> 
      <keyword match="unless"/> 
      <keyword match="for"/> 
      <keyword match="foreach"/> 
      <keyword match="until"/> 
      <keyword match="do"/> 
      <keyword match="continue"/> 
      <keyword match="not"/> 
      <keyword match="or"/> 
      <keyword match="and"/> 
      <keyword match="eq"/> 
      <keyword match="ne"/> 
      <keyword match="gt"/> 
      <keyword match="lt"/> 
  </keywords> 

</highlight>
